package com.junyuan.gsp.service;

import com.junyuan.gsp.bean.Menu;
import com.junyuan.gsp.bean.Result;
import com.junyuan.gsp.bean.Role;
import com.junyuan.gsp.bean.User;
import com.junyuan.gsp.dao.MenuDao;
import com.junyuan.gsp.dao.UserDao;
import com.junyuan.gsp.util.CipherUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import java.util.*;

/**
 * @Author: maxwellens
 */
@Service
public class UserService
{
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuDao menuDao;

    public List<User> findAllUsers()
    {
        Map<String, Object> map = new HashMap<>();
        return userDao.findUsers(map);
    }

    public Integer findAllUsersCount()
    {
        Map<String, Object> map = new HashMap<>();
        return userDao.findUsersCount(map);
    }


    public List<User> findUsers(Map<String, Object> map)
    {
        List<User> users = userDao.findUsers(map);
        for (User user : users)
        {
            String roles = user.getRoles();
            if (!StringUtils.isEmpty(roles))
            {
                String roleNames = roleService.findRoleNamesByIds(roles);
                user.setRoleNames(roleNames);
            }
        }
        return users;
    }

    public Integer findUsersCount(Map<String, Object> map)
    {
        return userDao.findUsersCount(map);
    }

    public Result findUsersResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = userDao.findUsersCount(map);
        List<User> data = findUsers(map);
        return new Result(data, count);
    }

    public User findUserById(Integer id)
    {
        User user = userDao.findUserById(id);
        return setUserRoles(user);
    }

    private User setUserRoles(User user)
    {
        String roles = user.getRoles();
        if (!StringUtils.isEmpty(roles))
        {
            String roleNames = roleService.findRoleNamesByIds(roles);
            user.setRoleNames(roleNames);
        }
        return user;
    }

    public User findUserByAccount(String name)
    {
        User user = userDao.findUserByAccount(name);
        return setUserRoles(user);
    }

    public void saveUser(User user)
    {
        if (user.getId() != null && user.getId() != 0)
        {
            userDao.updateUser(user);
        } else
        {
            user.setPassword(CipherUtil.encrypt(user.getAccount(), User.DEFAULT_PASSWORD));
            user.setIsEnabled(1);
            userDao.insertUser(user);
        }
    }

    public void deleteUserById(Integer id)
    {
        userDao.deleteUserById(id);
    }

    public void deleteUsers(String ids)
    {
        userDao.deleteUsers(ids);
    }

    public void toggleState(Integer id)
    {
        userDao.toggleState(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateStations(Integer userId, String stationIds)
    {
        String[] ids = stationIds.split(",");
        userDao.clearStations(userId);
        for (String id : ids)
        {
            Integer stationId = Integer.valueOf(id);
            userDao.insertStationUser(stationId, userId);
        }
    }

    public void resetPassword(Integer id)
    {
        User user = userDao.findUserById(id);
        String password = CipherUtil.encrypt(user.getAccount(), User.DEFAULT_PASSWORD);
        userDao.changePassword(id, password);
    }

    public void changePassword(Integer id, String newPassword)
    {
        User user = userDao.findUserById(id);
        String password = CipherUtil.encrypt(user.getName(), newPassword);
        userDao.changePassword(id, newPassword);
    }

    public List<Integer> findOwnedMenus(Integer userId)
    {
        Set<Integer> result = new HashSet<>();
        User user = userDao.findUserById(userId);
        if (user == null)
        {
            return new ArrayList<>();
        }
        String roles = user.getRoles();
        String[] roleIds = roles.split(",");
        for (String item : roleIds)
        {
            Integer roleId = Integer.valueOf(item);
            Role role = roleService.findRoleById(roleId);
            String menus = role.getMenus();
            String[] menuIds = menus.split(",");
            for (String m : menuIds)
            {
                Integer menuId = Integer.valueOf(m);
                result.add(menuId);
                Menu menu = menuDao.findMenuById(menuId);
                if (menu != null)
                {
                    result.add(menu.getParentId());
                }
            }
        }
        return new ArrayList<>(result);
    }
}
